package com.elvin.zoe.template;

import static com.elvin.zoe.template.HtmlTemplateResources.groupTemplate;
import static com.elvin.zoe.template.HtmlTemplateResources.messageCountTemplate;
import static com.elvin.zoe.template.HtmlTemplateResources.messageImageTemplate;
import static com.elvin.zoe.template.HtmlTemplateResources.messageTemplate;
import static com.elvin.zoe.template.HtmlTemplateResources.messageTimeSpan;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import com.elvin.zoe.pojo.CallMessage;
import com.elvin.zoe.pojo.Conversation;
import com.elvin.zoe.pojo.ImMessage;
import com.elvin.zoe.pojo.JiayuanMessage;
import com.elvin.zoe.pojo.Message;
import com.elvin.zoe.pojo.SmsMessage;
import com.elvin.zoe.pojo.TextMessage;
import com.elvin.zoe.pojo.structure.MessageCount;
import com.elvin.zoe.util.StringUtil;

public class HtmlTemplate {

    private static final int TIME_SPAN_MINUTES = 10;

    private static final String MY_DISPLAY_NAME = "Elwynn";
    private static final String SJP_DISPLAY_NAME = "Zooey";
    private static final String SJP_NAME = "沈佳萍";
    private static final String SJP_NAME_SHORT = "萍";
    private static final String ELV_NAME = "胡上上";

    protected final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    protected final SimpleDateFormat dateFormatDateOnly = new SimpleDateFormat("yyyy-MM-dd-EEE");
    protected final SimpleDateFormat dateFormatTimeOnly = new SimpleDateFormat("HH:mm");

    protected Conversation conversation;

    private final int PEEK_LENGTH = 15;


    public HtmlTemplate(Conversation conversation) {
        super();
        this.conversation = conversation;
    }


    protected String generateDaylyGroupHtml(Date day, List<Message> messages){

        String startTime = dateFormatTimeOnly.format(messages.get(0).getDateTime());
        Message lastMessage = messages.get(messages.size()-1);
		String endTime = dateFormatTimeOnly.format(lastMessage.getDateTime());
        if(lastMessage instanceof CallMessage){
        	CallMessage callMessage = (CallMessage)lastMessage;
        	endTime = dateFormatTimeOnly.format(callMessage.getEndDatetime());
        }

        String messagePeek = "";
        String messagePeekAuthor = "";

        TextMessage smsMessage = getFirstTextMessage(messages);
        int firstMessageNumber = messages.get(0).getMessageNumber();
        if(smsMessage != null){
            messagePeek = smsMessage.getText().length() < PEEK_LENGTH ? smsMessage.getText() : smsMessage.getText().substring(0, PEEK_LENGTH)+"...";
            messagePeek = messagePeek.replace(SJP_NAME, SJP_DISPLAY_NAME).replace(SJP_NAME_SHORT, SJP_DISPLAY_NAME);
            messagePeekAuthor = smsMessage.getType() == Message.OUTGOING ? MY_DISPLAY_NAME : SJP_DISPLAY_NAME;
        }

        String blockString = generateGroupBlock(messages);

        String dayString = dateFormatDateOnly.format(day);
        return groupTemplate.replaceAll("\\[GROUP.HEAD.DATE\\]", dayString)
                            .replace("[GROUP.HEAD.COUNT]", " (" + messages.size() + ") ")
                            .replace("[GROUP.HEAD.PEEK]", firstMessageNumber + " - " + messagePeekAuthor + " - " + messagePeek.replaceAll("<.*>", "").replaceAll("<", ""))
                            .replace("[GROUP.HEAD.TIME]", startTime + " - " + endTime)
                            .replace("[GROUP.BLOCK]", blockString)
                            .replace("[GROUP.BLOCK.ID]", dayString.replaceAll("-", ""));
    }

    private TextMessage getFirstTextMessage(List<Message> messages){
        for(Message message : messages){
            if (message instanceof TextMessage){
                return (TextMessage) message;
            }
        }
        return null;
    }

    private String generateGroupBlock(List<Message> messages){
        StringBuffer stringBuffer = new StringBuffer();
        Message lastMessage = null;
        for(Message message : messages){
            stringBuffer.append(getMessageTimeSpan(lastMessage, message));
            lastMessage = message;
            if (message instanceof SmsMessage) {
                stringBuffer.append(getMessageBlock((SmsMessage) message));
            }
            if (message instanceof CallMessage) {
                stringBuffer.append(getMessageBlock((CallMessage) message));
            }
            if (message instanceof ImMessage){
                stringBuffer.append(getMessageBlock((ImMessage) message));
            }
            if(message instanceof JiayuanMessage){
            	stringBuffer.append(getMessageBlock((JiayuanMessage) message));
            }
        }
        return stringBuffer.toString();
    }

    private String getMessageTimeSpan(Message lastMessage, Message thisMessage){
        if(lastMessage == null)
            return "";

        long lastEndingTime = lastMessage instanceof CallMessage ? getCallEndTime((CallMessage)lastMessage).getTime() : lastMessage.getDateTime().getTime();

        long timeDifference = thisMessage.getDateTime().getTime() - lastEndingTime;
        if(timeDifference / 1000L  > 60 * TIME_SPAN_MINUTES){
            long seconds = timeDifference / 1000L;
            String str = StringUtil.getTimeStringFromSeconds((int)seconds);
            return messageTimeSpan.replace("[MESSAGE.TIME.SPAN]", str);
        }
        return "";
    }

    private Object getMessageBlock(CallMessage message) {
        String messageText = "<font face='Wingdings'>&#40</font> On the phone with " + (message.getType() == Message.INCOMMING ? MY_DISPLAY_NAME : SJP_DISPLAY_NAME) + ". ";
        messageText += getCallTimeRange(message);
        messageText += " <br><span class='timeSpan'>"+StringUtil.getTimeStringFromSeconds(message.getDurationInSeconds())+"</span>";

        return getMessageBlock(message, messageText.replace("\n", "<br>"), "");
    }

    private String getCallTimeRange(CallMessage message){
        String startTime = dateFormatTimeOnly.format(message.getDateTime());
        String endTime = dateFormatTimeOnly.format(getCallEndTime(message));
        return startTime + " - " + endTime ;
    }
    private Date getCallEndTime(CallMessage message){
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(message.getDateTime());
        calendar.add(Calendar.SECOND, message.getDurationInSeconds());
        return calendar.getTime();
    }

    private String getMessageBlock(SmsMessage message){
        String imageReplacement = "";
        if(message.getImageName() != null){
            imageReplacement = messageImageTemplate.replace("[MESSAGE.IMAGE.NAME]", message.getImageName());
        }

        return getMessageBlock(message, message.getText(), imageReplacement);
    }

    private String getMessageBlock(ImMessage message){
        String messageText = "<font face='Webdings'>&#94</font> " + message.getText();
        messageText = messageText.replaceAll(ImMessage.LINE_BREAK, "<BR><font face='Webdings'>&#94</font> ");
        return getMessageBlock(message, messageText, "");
    }

    private String getMessageBlock(JiayuanMessage message){
        String messageText = "<font face='Webdings'>&#153</font> " + message.getText();
        return getMessageBlock(message, messageText, "");
    }

    private String getMessageBlock(Message message, String messageText, String messageImage) {

        messageText = messageText.replace(SJP_NAME, SJP_DISPLAY_NAME).replace(SJP_NAME_SHORT, SJP_DISPLAY_NAME).replace(ELV_NAME, MY_DISPLAY_NAME);


        String replacement = messageTemplate.replace("[MESSAGE.DATETIME]", dateFormat.format(message.getDateTime()))
                                            .replace("[MESSAGE.TEXT]", messageText)
                                            .replace("[MESSAGE.IMAGE]", messageImage);

        replacement = replacement.replace("[MESSAGE.AUTHOR.NAME.LEFT]",      message.getType() == Message.INCOMMING ? SJP_DISPLAY_NAME : "")
                                 .replace("[MESSAGE.AUTHOR.NAME.RIGHT]",     message.getType() == Message.INCOMMING ? "" : MY_DISPLAY_NAME)
                                 .replace("[MESSAGE_TEXT_STYLE_CLASS]",      message.getType() == Message.INCOMMING ? "messageIncomming" : "messageOutgoing")
                                 .replace("[AUTHOR_NAME_STYLE_CLASS_LEFT]",  message.getType() == Message.INCOMMING ? "authorNameIncomming" : "")
                                 .replace("[AUTHOR_NAME_STYLE_CLASS_RIGHT]", message.getType() == Message.INCOMMING ? "" : "authorNameOutgoing")
                                 .replace("[MESSAGE.NUMBER]", message.getMessageNumber()+"")
                                 ;
        return replacement;
    }

    protected String getMessageCounts(MessageCount messageCount) {
        String menuFoot = messageCountTemplate.replace("[SMS.COUNT]", messageCount.getSmsMessageCount() + "")
                                              .replace("[CALL.COUNT]", StringUtil.getTimeStringFromSeconds(messageCount.getCallMessageDuration()))
                                              .replace("[MSN.COUNT]", messageCount.getMsnMessageCount() + "")
                                              ;
        return menuFoot;
    }

    public Conversation getConversation() {
        return conversation;
    }

    public void setConversation(Conversation conversation) {
        this.conversation = conversation;
    }

}
